package com.fingard.dsp.bank.directbank.citic43;

import com.fingard.common.utils.json.JSONUtils;
import com.fingard.db.JDBCHelper;
import com.fingard.dsp.bank.directConfig.FtpSet;
import com.fingard.net.FtpPortClient;
import com.fingard.net.FtpReceiver;
import com.fingard.util.FtpUtil;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;
import net.sf.json.JSONObject;

import java.io.File;
import java.sql.Connection;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import com.fingard.FGBiz;
import com.fingard.constant.Format;
import com.fingard.dsp.bank.directbank.FailCode;
import com.fingard.dsp.bank.directbank.PaymentState;
import com.fingard.dsp.bank.directbank.bankInterface.IBatPayRec;
import com.fingard.dsp.bank.directbank.citic43.CITIC43Util.StrZipUtil;
import com.fingard.dsp.bank.reqrespobj.batpayrec.ReqBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.ReqQryBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.RetAtsBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.RetAtsQryBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.detail.RetAtsBatPayRecDetail;
import com.fingard.dsp.bank.reqrespobj.single.detail.ReqPayRecDetail;
import com.fingard.io.FileHelper;
import com.fingard.net.ConnState;
import com.fingard.text.StringHelper;

public class CITIC43BatPayRec extends CITIC43Base implements IBatPayRec {
    @Override
    public RetAtsBatPayRec d_1988_BatPay(ReqBatPayRec p_req1988) throws Exception {
        RetAtsBatPayRec retAts = null;
        if (p_req1988.reqHeader.commandCode.equals("1988F001")) {
            retAts = twoGen_d_1988_BatPay(p_req1988);
        } else {
            retAts = oneGen_d_1988_BatPay(p_req1988);
        }
        return retAts;
    }

    public RetAtsBatPayRec oneGen_d_1988_BatPay(ReqBatPayRec p_req1988) {
        RetAtsBatPayRec retAts = new RetAtsBatPayRec(p_req1988.reqHeader);
        try {
            if (p_req1988.isSameIsPrivate() == false) {
                retAts.respCode = "-1";
                retAts.respInfo = "银行支付批暂不支持同时存在对公、对私批付！";

            } else {
                String payDate = Format.Date8Format.format(p_req1988.getPayDateTime());
                int index = 1;
                String tmpBatchNo = "";
                String tmpBatFilePath = "";
                //region  获取批次号 根据当日文件夹数按序往上累加，使用同步代码块防止并发
                synchronized (this) {
                    String dirPath = FGBiz.dspCenter.dspSet.dataDirPath + File.separator + "tempfile" + File.separator + "CITIC43" + File.separator + "DF" + p_req1988.ownAct + File.separator + payDate;
                    File tmpFile = new File(dirPath);
                    if (!tmpFile.exists()) {
                        tmpFile.mkdirs();
                    } else {
                        index = tmpFile.listFiles().length + 1;
                    }
                    tmpBatchNo = StringHelper.padLeft(String.valueOf(index), 4, '0');
                    tmpBatFilePath = dirPath + File.separator + p_req1988.reqBatchNO + "-" + tmpBatchNo;
                    File reqDirc = new File(tmpBatFilePath);
                    reqDirc.mkdir();
                }
                //endregion

                String fileName = p_req1988.ownAct + Format.DateTime14Format.format(p_req1988.getPayDateTime()) + tmpBatchNo + ".txt";//商户号(15)+日期时间(YYYYMMDDHHMMSS)+批次号(当天唯一(0001-9999))
                StringBuilder fileContent = new StringBuilder();
                //文件头：商户号|批次号|上传日期(YYYYMMDD)|总金额|总笔数|代付方式（01：对公、02：对私）|保留域1|保留域2
                fileContent.append(p_req1988.ownAct);
                fileContent.append(fieldUnionChar);
                fileContent.append(tmpBatchNo);
                fileContent.append(fieldUnionChar);
                fileContent.append(payDate);
                fileContent.append(fieldUnionChar);
                fileContent.append(StringHelper.amountMultiply100(p_req1988.totalAmt));
                fileContent.append(fieldUnionChar);
                fileContent.append(p_req1988.totalNum);
                fileContent.append(fieldUnionChar);
                fileContent.append("1".equals(p_req1988.isPrivate) ? "02" : "01");
                fileContent.append(fieldUnionChar);
                fileContent.append(p_req1988.abstractATS);
                fileContent.append(fieldUnionChar);
                fileContent.append("");
                fileContent.append(lineUnionChar);
                while (p_req1988.readRecord()) {
                    //报文体：商户号、商户订单号、金额、账号类型（01:银行卡  02:存折）、账号、户名、开户行省、开户行市、开户行名称、证件类型、证件号码、手机号、账单类型、用途、支行、保留域1、保留域2
                    ReqPayRecDetail tmpDetail = p_req1988.readedDetail;
                    fileContent.append(tmpDetail.payAct);//商户号
                    fileContent.append(fieldUnionChar);
                    fileContent.append(tmpDetail.askNumber);//商户订单号
                    fileContent.append(fieldUnionChar);
                    fileContent.append(StringHelper.amountMultiply100(tmpDetail.payAmount));//金额
                    fileContent.append(fieldUnionChar);
                    fileContent.append(tmpDetail.recAct.length() >= 20 ? "02" : "01");//账号类型（01:银行卡  02:存折）
                    fileContent.append(fieldUnionChar);
                    fileContent.append(tmpDetail.recAct);//账号
                    fileContent.append(fieldUnionChar);
                    fileContent.append(tmpDetail.recName);//户名
                    fileContent.append(fieldUnionChar);
                    fileContent.append("");//开户行省
                    fileContent.append(fieldUnionChar);
                    fileContent.append("");//开户行市
                    fileContent.append(fieldUnionChar);
                    fileContent.append("");//开户行名称
                    fileContent.append(fieldUnionChar);
                    fileContent.append("01");//证件类型
                    fileContent.append(fieldUnionChar);
                    fileContent.append(tmpDetail.certNum);//证件号码
                    fileContent.append(fieldUnionChar);
                    fileContent.append("");//手机号
                    fileContent.append(fieldUnionChar);
                    fileContent.append("");//账单类型
                    fileContent.append(fieldUnionChar);
                    fileContent.append(tmpDetail.purpose);//用途
                    fileContent.append(fieldUnionChar);
                    fileContent.append("");//支行
                    fileContent.append(fieldUnionChar);
                    fileContent.append("");//保留域1
                    fileContent.append(fieldUnionChar);
                    fileContent.append("");//保留域2
                    fileContent.append(fieldUnionChar);
                    fileContent.append(getBankConfig().getValueAsString("payAct"));//付款方账号/卡号
                    fileContent.append(fieldUnionChar);
                    fileContent.append(getBankConfig().getValueAsString("payActName"));//付款方户名
                    fileContent.append(fieldUnionChar);
                    fileContent.append("");//付款通道标识
                    fileContent.append(fieldUnionChar);
                    fileContent.append("");//收款方开户行行号
                    fileContent.append(fieldUnionChar);
                    fileContent.append("");//付款方账户类型
                    fileContent.append(fieldUnionChar);
                    fileContent.append("");//收款方账户类型
                    fileContent.append(fieldUnionChar);
                    fileContent.append("");//资金来源（业务产品标识）
                    fileContent.append(lineUnionChar);

                }
                String fileContentStr = StringHelper.trimEnd(fileContent.toString(), lineUnionChar);
                String filePath = tmpBatFilePath + File.separator + fileName;
                FileHelper.writeFile(filePath, fileContentStr, getCharset());
                WriteBankLogLn("已生成批付文件，路径位于：" + filePath);

                Map<String, String> data = new HashMap<String, String>();
                data.put("batchNo", tmpBatchNo);
                data.put("bizCode", "H0001");
                data.put("countItems", p_req1988.totalNum);
                data.put("fileName", fileName);
                data.put("fileContent", StrZipUtil.zipFile(filePath, getCharset()));
                data.put("merchantId", p_req1988.ownAct);
                data.put("signType", "1");
                data.put("sumAmount", StringHelper.amountMultiply100(p_req1988.totalAmt));
                data.put("orderDate", payDate);
                data.put("orderTime", Format.Time6Format.format(p_req1988.getPayDateTime()));
                data.put("version", "2.0");
                data.put("key", getBankConfig().getMapValueByKey("keyMapping", p_req1988.ownAct));
                String signMsg = signMsg(data);
                data.put("signMsg", signMsg);
                //data.put("key", "");

                String[] tmpStrRet = sendToBank(JSONUtils.map2JSON(data), bankFront.getUrl("1988"));
                if (tmpStrRet[0].length() == 0) {
                    tmpStrRet[1] = StrZipUtil.unicode2String(tmpStrRet[1]);
                    WriteBankLogLn("CITIC43批量付款银行返回的原文：" + tmpStrRet[1]);
                    JSONObject json = JSONObject.fromObject(tmpStrRet[1]);
                    String retSignMsg = json.getString("signMsg");
                    Map<String, String> retData = json2Map(tmpStrRet[1], "batchNo,bizCode,errCode,fileName,merchantId,respDate,respTime,signType,version,key");
                    retData.put("key", getBankConfig().getMapValueByKey("keyMapping", p_req1988.ownAct));
                    if (StringHelper.isNullOrEmpty(retSignMsg) || retSignMsg.equals(returnSignMsgCheck(retData))) {
                        retAts.respCode = "0";
                        retAts.respInfo = json.getString("errCode") + "-" + json.getString("errMsg");
                        retAts.reqSeqID = p_req1988.reqBatchNO;
                        retAts.transState = json.getString("errCode");
                        retAts.payInfoCode = retAts.transState;
                    } else {
                        retAts.respCode = "-1";
                        retAts.respInfo = "验签失败";
                    }
                } else if (tmpStrRet[0].equals(ConnState.FAIL) || tmpStrRet[0].equals(FailCode.E9981)) {
                    retAts.respCode = "0";
                    retAts.respInfo = tmpStrRet[1];
                    retAts.reqSeqID = p_req1988.reqBatchNO;
                    retAts.transState = PaymentState.FAIL_Batch;
                    retAts.payInfoCode = tmpStrRet[0];
                } else {
                    retAts.respCode = "-1";
                    retAts.respInfo = tmpStrRet[1];
                }
            }
        } catch (Exception e) {
            retAts.respCode = "-1";
            retAts.respInfo = e.toString();
            e.printStackTrace();
        }
        if (retAts.respCode.equals("-1") && StringHelper.isNullOrEmpty(retAts.reqSeqID)) {
            retAts.reqSeqID = p_req1988.reqBatchNO;
        }
        retAts.writeRetToATS();
        return retAts;
    }

    public RetAtsBatPayRec twoGen_d_1988_BatPay(ReqBatPayRec p_req1988) throws Exception {
        RetAtsBatPayRec retAts = new RetAtsBatPayRec(p_req1988.reqHeader);
        Connection conn = FGBiz.getLocalDbConn();
        try {
            String dirPath = getTempFileDirectory() + File.separator + "uploads";
            String filePrefix = this.getBankConfig().getValueAsString("filePrefix");
            String fileName = filePrefix + addCharRight(20, '0', p_req1988.reqBatchNO) + ".utf";
            Integer totalCount = new Integer(0);
            String fileContent = write1988FileContent(p_req1988, totalCount);
            String filePath = dirPath + File.separator + fileName;
            FileHelper.writeFile(filePath, fileContent, "UTF-8");
            WriteBankLogLn("已生成批付文件，路径位于：" + filePath);  //生成的文件怎样与银行交互
            WriteBankLogLn(p_req1988.reqBatchNO + "批号代收文件处理完毕,一共" + p_req1988.getTotalNum() + "条明细.");
            WriteBankLogLn("开始上传文件至FTP...");
            FtpSet ftpSet = bankFront.getFtpSet("batPay");
            String ftpFilePath = StringHelper.trimEndFileSp(ftpSet.upDir) + "/" + fileName;
            int result = FtpUtil.ftpUploading(ftpSet, filePath, ftpFilePath);
            //int result = 0;
            if (result == 0 || result == 1) {
                WriteBankLogLn("上传批量付款文件成功...");
            } else {
                WriteBankLogLn("上传批量付款文件失败...");
                retAts.respCode = "-1";

                retAts.respInfo = "上传批量付款文件失败...";
                return retAts;
            }

            XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象
            StringBuilder sbMsg = new StringBuilder();
            sbMsg.append("012509801 012590090000200012590090000200JNWL    F001           ");
            xmlWriter.writeStartDocByDeclaration("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
            xmlWriter.writeStartElement("ROOT");
            xmlWriter.writeElementString("requestId", p_req1988.reqHeader.transSeqID);
            xmlWriter.writeElementString("transtyp", "request");
            xmlWriter.writeElementString("transcode", "F001");
            xmlWriter.writeElementString("transchl", "0002");//渠道码  社保
            xmlWriter.writeElementString("txdate", Format.Date8Format.format(Format.Date10Format.parse(p_req1988.payDate)));
            xmlWriter.writeElementString("txtime", p_req1988.payTime.replace(":", ""));
            xmlWriter.writeElementString("stdfiletp", "1");//1-文本文件txt
            xmlWriter.writeElementString("std400mxid", fileName);//明细文件ID
            xmlWriter.writeElementString("std400mxbs", p_req1988.totalNum);//明细笔数
            xmlWriter.writeElementString("stdtrancur", "001");//明细汇总币种
            xmlWriter.writeElementString("std400hjje", p_req1988.totalAmt);//明细汇总金额
            xmlWriter.writeEndElement();
            xmlWriter.writeEndDocument();
            sbMsg.append(xmlWriter.toXmlString());
            String contentLength = String.format("%08d", sbMsg.length());
            sbMsg.insert(0, contentLength);
            String[] bankResult = sendToBank(sbMsg.toString());
            if (bankResult[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(bankResult[1], tmpSbMsg);
                if (tmpBkReader != null) {
                    retAts.respCode = "0";
                    retAts.respInfo = "Paying";
                    retAts.reqSeqID = p_req1988.reqBatchNO;
                    retAts.transState = "Paying";
                    retAts.payInfoCode = retAts.transState;
                    //记录批次号对应的银行支付批次号，供查询状态接口使用
                    String uuid = UUID.randomUUID().toString().replaceAll("-", "");
                    JDBCHelper.update(conn, INSERTSEQ, new Object[]{uuid, p_req1988.reqHeader.bankCode, Format.Date8Format.format(new Date()), p_req1988.reqBatchNO, tmpBkReader.getFirstText("/ROOT/std400plxh"), tmpBkReader.getFirstText("/ROOT/std400chno")});
                } else {
                    retAts.respCode = "-1";
                    retAts.respInfo = tmpSbMsg.toString();
                }
            } else if (bankResult[0].equals(ConnState.FAIL)) {
                retAts.respCode = "0";
                retAts.respInfo = bankResult[1];
                retAts.reqSeqID = p_req1988.reqBatchNO;
                retAts.transState = PaymentState.FAIL_Batch;
                retAts.payInfoCode = bankResult[0];
            } else {
                retAts.respCode = "-1";
                retAts.respInfo = bankResult[1];
            }
        } catch (Exception e) {
            retAts.respCode = "-1";
            retAts.respInfo = e.toString();
            e.printStackTrace();
        } finally {
            if (conn != null) {
                conn.close();
            }
        }
        if (retAts.respCode.equals("-1") && StringHelper.isNullOrEmpty(retAts.reqSeqID)) {
            retAts.reqSeqID = p_req1988.reqBatchNO;
        }
        retAts.writeRetToATS();
        return retAts;
    }

    private RetAtsQryBatPayRec twoGen_d_1998_QryBatPay(ReqQryBatPayRec p_req1998) throws Exception {
        //返回ATS的对象
        boolean isNext = false;
        RetAtsQryBatPayRec retAts = new RetAtsQryBatPayRec(p_req1998.reqHeader);
        Connection conn = FGBiz.getLocalDbConn();
        try {
            XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象
            StringBuilder sbMsg = new StringBuilder();
            sbMsg.append("012509801 012590090000200012590090000200JNWL    F002           ");
            xmlWriter.writeStartDocByDeclaration("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
            xmlWriter.writeStartElement("ROOT");
            xmlWriter.writeElementString("requestId", getQryTransID());
            xmlWriter.writeElementString("transtyp", "request");
            xmlWriter.writeElementString("transcode", "F002");
            xmlWriter.writeElementString("transchl", "0002");//渠道码  社保
            xmlWriter.writeElementString("stdbegdate", Format.Date8Format.format(Format.DateTimeFormat.parse(p_req1998.bgnDate)));
            xmlWriter.writeElementString("stdenddate", Format.Date8Format.format(Format.DateTimeFormat.parse(p_req1998.bgnDate)));
            xmlWriter.writeElementString("stdtrnstcd", "00");//交易状态
            xmlWriter.writeElementString("std400cxym", "1");//查询页码
            xmlWriter.writeElementString("std400myts", "10");//每页条数
            xmlWriter.writeElementString("stdchldate", Format.Date8Format.format(Format.DateTimeFormat.parse(p_req1998.bgnDate)));//渠道日期
            xmlWriter.writeElementString("std400brno", "");//网点号
            xmlWriter.writeElementString("std400cxgd", "5");//查询级别0:网点1:账务中心2:分行3:区域中心4:清算账务行 5:总行

            Map<String, Object> selMap = JDBCHelper.execQuerySingle(conn, SELECTSEQ, new Object[]{p_req1998.reqBatchNO, p_req1998.reqHeader.bankCode});
            if (selMap.size() > 0) {
                xmlWriter.writeElementString("std400plxh", selMap.get("BANKREQSEQID").toString());//批量支付流水号
                xmlWriter.writeElementString("std400chno", selMap.get("BANKREQBATCHNO").toString());//渠道流水号
            } else {
                retAts.respCode = "0";
                retAts.respInfo = "交易流水号关联映射异常,支付失败";
                retAts.reqSeqID = p_req1998.reqBatchNO;
                retAts.transState = "88";
                retAts.payInfoCode = retAts.transState;
                retAts.writeAfterDetail();
                return retAts;
            }
            xmlWriter.writeElementString("stdtranchl", "CBPP");//渠道标识
            xmlWriter.writeEndElement();
            xmlWriter.writeEndDocument();
            sbMsg.append(xmlWriter.toXmlString());
            String contentLength = String.format("%08d", sbMsg.length());
            sbMsg.insert(0, contentLength);
            String[] bankResult = sendToBank(sbMsg.toString());
            if (bankResult[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(bankResult[1], tmpSbMsg);
                if (tmpBkReader != null) {
                    String std400dqts = tmpBkReader.getFirstText("/ROOT/std400dqts");
                    if (StringHelper.hasAnyChar(std400dqts) && Integer.parseInt(std400dqts) > 0) {
                        while (tmpBkReader.read("/ROOT/LIST/ROWS")) {
                            if (tmpBkReader.readedXElement.getSingleText("std400plxh").equals(selMap.get("BANKREQSEQID").toString())) {
                                if (tmpBkReader.readedXElement.getSingleText("stdtrnstcd").equals("99")) {
                                    isNext = true;
                                    break;
                                } else if (tmpBkReader.readedXElement.getSingleText("stdtrnstcd").equals("88")) {
                                    retAts.respCode = "0";
                                    retAts.respInfo = "支付失败";
                                    retAts.reqSeqID = p_req1998.reqBatchNO;
                                    retAts.transState = "88";
                                    retAts.payInfoCode = retAts.transState;
                                    retAts.writeAfterDetail();
                                    return retAts;
                                }
                            }
                        }
                    }
                } else {
                    retAts.respCode = "-1";
                    retAts.respInfo = tmpSbMsg.toString();
                }
                String stdkeyword = "";
                if (isNext) {
                    isNext = false;
                    xmlWriter = new XmlTextWriter();//发银行报文的XML对象
                    sbMsg = new StringBuilder();
                    sbMsg.append("012509801 012590090000200012590090000200JNWL    F003           ");
                    xmlWriter.writeStartDocByDeclaration("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
                    xmlWriter.writeStartElement("ROOT");
                    xmlWriter.writeElementString("requestId", getQryTransID());
                    xmlWriter.writeElementString("transtyp", "request");
                    xmlWriter.writeElementString("transcode", "F003");
                    xmlWriter.writeElementString("transchl", "0002");//渠道码  社保
                    xmlWriter.writeElementString("txdate", Format.Date8Format.format(Format.DateTimeFormat.parse(p_req1998.bgnDate)));
                    xmlWriter.writeElementString("txtime", Format.Time6Format.format(Format.DateTimeFormat.parse(p_req1998.bgnDate)));
                    xmlWriter.writeElementString("stdkeyword", "");//---
                    xmlWriter.writeElementString("stdchldate", Format.Date8Format.format(Format.DateTimeFormat.parse(p_req1998.bgnDate)));//---
                    xmlWriter.writeElementString("stdprnttyp", "0");//---打印类型  0-不打印1-收费凭证打印2-冲正凭证打印3-明细清单打印
                    xmlWriter.writeElementString("stdrqsttyp", "1");//1：申请请求 2：状态查询 先发1生成文件，再发2查询生成文件状态
                    if (selMap.size() > 0) {
                        xmlWriter.writeElementString("std400plxh", selMap.get("BANKREQSEQID").toString());//批量支付流水号
                        xmlWriter.writeElementString("std400chno", selMap.get("BANKREQBATCHNO").toString());//渠道流水号
                    } else {
                        retAts.respCode = "0";
                        retAts.respInfo = "交易流水号关联映射异常,支付失败";
                        retAts.reqSeqID = p_req1998.reqBatchNO;
                        retAts.transState = "88";
                        retAts.payInfoCode = retAts.transState;
                        retAts.writeAfterDetail();
                        return retAts;
                    }
                    xmlWriter.writeElementString("stdtranchl", "CBPP");//渠道标识
                    xmlWriter.writeEndElement();
                    xmlWriter.writeEndDocument();
                    sbMsg.append(xmlWriter.toXmlString());
                    contentLength = String.format("%08d", sbMsg.length());
                    sbMsg.insert(0, contentLength);
                    bankResult = sendToBank(sbMsg.toString());
                    if (bankResult[0].length() == 0) {
                        tmpSbMsg = new StringBuilder();
                        tmpBkReader = loadBankRespXmlReader(bankResult[1], tmpSbMsg);
                        if (tmpBkReader != null) {
                            stdkeyword = tmpBkReader.getFirstText("/ROOT/BODY/stdkeyword");
                            if (StringHelper.hasAnyChar(stdkeyword)) {
                                isNext = true;
                            }
                        } else {
                            retAts.respCode = "-1";
                            retAts.respInfo = tmpSbMsg.toString();
                        }
                    } else if (bankResult[0].equals(ConnState.FAIL)) {
                        retAts.respCode = "0";
                        retAts.respInfo = bankResult[1];
                        retAts.reqSeqID = p_req1998.reqBatchNO;
                        retAts.transState = PaymentState.FAIL_Batch;
                        retAts.payInfoCode = bankResult[0];
                    } else {
                        retAts.respCode = "-1";
                        retAts.respInfo = bankResult[1];
                    }
                } else {
                    retAts.respCode = "0";
                    retAts.respInfo = "Paying";
                    retAts.reqSeqID = p_req1998.reqBatchNO;
                    retAts.transState = "Paying";
                    retAts.payInfoCode = retAts.transState;
                    retAts.writeAfterDetail();
                    return retAts;
                }

                if (isNext) {
                    isNext = false;
                    int queryTime = getBankConfig().getValueAsInt("queryTime");
                    while (queryTime-->0) {
                        Thread.sleep(getBankConfig().getValueAsInt("waitTime"));//等待银行处理
                        xmlWriter = new XmlTextWriter();//发银行报文的XML对象
                        sbMsg = new StringBuilder();
                        sbMsg.append("012509801 012590090000200012590090000200JNWL    F003           ");
                        xmlWriter.writeStartDocByDeclaration("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
                        xmlWriter.writeStartElement("ROOT");
                        xmlWriter.writeElementString("requestId", getQryTransID());
                        xmlWriter.writeElementString("transtyp", "request");
                        xmlWriter.writeElementString("transcode", "F003");
                        xmlWriter.writeElementString("transchl", "0002");//渠道码  社保
                        xmlWriter.writeElementString("txdate", Format.Date8Format.format(Format.DateTimeFormat.parse(p_req1998.bgnDate)));
                        xmlWriter.writeElementString("txtime", Format.Time6Format.format(Format.DateTimeFormat.parse(p_req1998.bgnDate)));
                        xmlWriter.writeElementString("stdkeyword", stdkeyword);//---
                        xmlWriter.writeElementString("stdchldate", Format.Date8Format.format(Format.DateTimeFormat.parse(p_req1998.bgnDate)));//---
                        xmlWriter.writeElementString("stdprnttyp", "0");//---
                        xmlWriter.writeElementString("stdrqsttyp", "2");//1：申请请求 2：状态查询 先发1生成文件，再发2查询生成文件状态
                        xmlWriter.writeElementString("std400plxh", selMap.get("BANKREQSEQID").toString());//批量支付流水号
                        xmlWriter.writeElementString("stdtranchl", "CBPP");//渠道标识
                        xmlWriter.writeElementString("std400chno", selMap.get("BANKREQBATCHNO").toString());//渠道流水号
                        xmlWriter.writeEndElement();
                        xmlWriter.writeEndDocument();
                        sbMsg.append(xmlWriter.toXmlString());
                        contentLength = String.format("%08d", sbMsg.length());
                        sbMsg.insert(0, contentLength);
                        bankResult = sendToBank(sbMsg.toString());
                        if (bankResult[0].length() == 0) {
                            tmpSbMsg = new StringBuilder();
                            tmpBkReader = loadBankRespXmlReader(bankResult[1], tmpSbMsg);
                            if (tmpBkReader != null) {
                                String stateFlag = tmpBkReader.getFirstText("/ROOT/BODY/std400clzt");
                                if ("3".equals(stateFlag) || "2".equals(stateFlag)) {
                                    isNext = true;
                                    break;
                                }
                            } else {
                                retAts.respCode = "-1";
                                retAts.respInfo = tmpSbMsg.toString();
                            }
                        } else if (bankResult[0].equals(ConnState.FAIL)) {
                            retAts.respCode = "0";
                            retAts.respInfo = bankResult[1];
                            retAts.reqSeqID = p_req1998.reqBatchNO;
                            retAts.transState = PaymentState.FAIL_Batch;
                            retAts.payInfoCode = bankResult[0];
                            break;
                        } else {
                            retAts.respCode = "-1";
                            retAts.respInfo = bankResult[1];
                        }
                    }
                    if(isNext){
                        //下载文件
                        FtpSet ftpSet = bankFront.getFtpSet("batPay");
                        String fileName = tmpBkReader.getFirstText("/ROOT/BODY/std400mxid");
                        String downFilePath = StringHelper.trimEndFileSp(ftpSet.downDir) + "/" + fileName;
                        String localSavePath = getTempFileDirectory() + File.separator + "downloads" + File.separator + fileName;
                        FtpPortClient ftpPtClient = new FtpPortClient(ftpSet);
                        ftpPtClient.connect();
                        FtpReceiver ftpReceiver = ftpPtClient.downloadFile(downFilePath, localSavePath);
                        if (ftpReceiver.isCompleted) {
                            WriteBankLogLn("成功下载批量支付结果文件:" + fileName + "至" + localSavePath);
                        } else {
                            WriteBankLogLn(fileName + "批量支付结果文件下载失败:" + ftpReceiver.connMsg + "+" + ftpReceiver.connState);
                            retAts.respCode = "-1";
                            retAts.respInfo = fileName + "批量支付结果文件下载失败:" + ftpReceiver.connMsg + "+" + ftpReceiver.connState;
                            retAts.writeAfterDetail();
                            return retAts;
                        }
                        if (FileHelper.existFile(localSavePath)) {
                            String[] fileContent = FileHelper.readFileText(localSavePath, "UTF-8").split("\n");
                            retAts.reqSeqID = p_req1998.reqBatchNO;//客户流水号
                            retAts.respInfo = "查询成功";//交易状态信息
                            retAts.payInfoCode = retAts.respInfo;//交易状态
                            retAts.respCode = "0";
                            for (int i = 0; i < fileContent.length; i++) {
                                if (fileContent[i] != null) {
                                    RetAtsBatPayRecDetail tmpRetDetail = new RetAtsBatPayRecDetail();
                                    tmpRetDetail.payAct = p_req1998.ownAct;
                                    String[] fields = fileContent[i].replaceAll("\"", "").split(new String(new byte[]{3}));
                                    tmpRetDetail.payAct = p_req1998.ownAct;
                                    tmpRetDetail.payName = fields[27];
                                    tmpRetDetail.recAct = fields[34];//收款人账号
                                    tmpRetDetail.recName = fields[35];//收款人名称
                                    tmpRetDetail.postScript = fields[37];//批内流水号
                                    tmpRetDetail.payAmount = getPayAmount(fields[20]);//金额
                                    tmpRetDetail.memo = fields[38];//备注
                                    tmpRetDetail.result = fields[83];
                                    tmpRetDetail.payInfoCode = tmpRetDetail.result;
                                    retAts.writeRetDetail(tmpRetDetail);
                                }
                            }
                        } else {
                            retAts.respCode = "-1";
                            retAts.respInfo = "查询成功，未获取到文件";
                        }
                    } else {
                        retAts.respCode = "0";
                        retAts.respInfo = "Paying";
                        retAts.reqSeqID = p_req1998.reqBatchNO;
                        retAts.transState = "Paying";
                        retAts.payInfoCode = retAts.transState;
                        retAts.writeAfterDetail();
                        return retAts;
                    }
                } else {
                    retAts.respCode = "0";
                    retAts.respInfo = "Paying";
                    retAts.reqSeqID = p_req1998.reqBatchNO;
                    retAts.transState = "Paying";
                    retAts.payInfoCode = retAts.transState;
                    retAts.writeAfterDetail();
                    return retAts;
                }
            } else if (bankResult[0].equals(ConnState.FAIL)) {
                retAts.respCode = "0";
                retAts.respInfo = bankResult[1];
                retAts.reqSeqID = p_req1998.reqBatchNO;
                retAts.transState = PaymentState.FAIL_Batch;
                retAts.payInfoCode = bankResult[0];
                retAts.writeAfterDetail();
            } else {
                retAts.respCode = "-1";
                retAts.respInfo = bankResult[1];
            }
        } catch (Exception e) {
            retAts.respCode = "-1";
            retAts.respInfo = e.toString();
            WriteBankLogLn("批量代发异常：" + e);
            e.printStackTrace();
        } finally {
            conn.close();
        }
        retAts.writeAfterDetail();
        return retAts;
    }


    public RetAtsQryBatPayRec oneGen_d_1998_QryBatPay(ReqQryBatPayRec p_req1998) throws Exception {
        //返回ATS的对象
        RetAtsQryBatPayRec retAts = new RetAtsQryBatPayRec(p_req1998.reqHeader);
        try {
            String payDate = Format.Date8Format.format(p_req1998.getBgnDateTime());
            //根据ats批次号获取提交银行的批次号
            String dirPath = FGBiz.dspCenter.dspSet.dataDirPath + File.separator + "tempfile" + File.separator + "CITIC43" + File.separator + "DF" + p_req1998.ownAct + File.separator + payDate;
            boolean hasMatched = false;
            String tmpBatchNo = "";
            String matchFlag = p_req1998.reqBatchNO + "-";
            File dir = new File(dirPath);
            if (dir.exists()) {
                File[] tmpFiles = dir.listFiles();
                for (File file : tmpFiles) {
                    if (file.getName().contains(matchFlag)) {
                        hasMatched = true;
                        tmpBatchNo = file.getName().replace(matchFlag, "");
                    }
                }
            }
            if (hasMatched) {
                String fileName = p_req1998.ownAct + Format.DateTime14Format.format(p_req1998.getBgnDateTime()) + tmpBatchNo + ".txt";

                Map<String, String> data = new HashMap<String, String>();
                data.put("batchNo", tmpBatchNo);
                data.put("bizCode", "H0002");
                data.put("fileName", fileName);
                data.put("merchantId", p_req1998.ownAct);
                data.put("signType", "1");
                data.put("orderDate", payDate);
                data.put("orderTime", Format.Time6Format.format(p_req1998.getBgnDateTime()));
                data.put("version", "2.0");
                data.put("key", getBankConfig().getMapValueByKey("keyMapping", p_req1998.ownAct));
                String signMsg = querySignMsg(data);
                data.put("signMsg", signMsg);
                //data.put("key", "");

                String[] tmpStrRet = sendToBank(JSONUtils.map2JSON(data), bankFront.getUrl("1998"));
                if (tmpStrRet[0].length() == 0) {
                    tmpStrRet[1] = StrZipUtil.unicode2String(tmpStrRet[1]);
                    WriteBankLogLn("CITIC43付款查询银行返回的原文：" + tmpStrRet[1]);
                    JSONObject json = JSONObject.fromObject(tmpStrRet[1]);
                    String retSignMsg = json.getString("signMsg");
                    //version,signType,merchantId,respDate,respTime,resultFileName,batchNo,signMsg,errCode,errMsg,resultFileContent,key,ansReserved1,ansReserved2,queryId
                    Map<String, String> retData = json2Map(tmpStrRet[1], "fileName,version,signType,merchantId,respDate,respTime,resultFileName,batchNo,signMsg,errCode,errMsg,resultFileContent,key");
                    retData.put("key", getBankConfig().getMapValueByKey("keyMapping", p_req1998.ownAct));
                    //Map<String, String> retData = json2Map(tmpStrRet[1], "batchNo,bizCode,errCode,fileName,merchantId,respDate,respTime,signType,version,key");
                    if (StringHelper.isNullOrEmpty(retSignMsg) || retSignMsg.equals(returnSignMsgCheck(retData))) {
                        String retFileName = json.getString("resultFileName");
                        if (StringHelper.isNullOrEmpty(retFileName)) {
                            retAts.respCode = "0";
                            retAts.respInfo = json.getString("errMsg");
                            retAts.reqSeqID = p_req1998.reqBatchNO;
                            retAts.payInfoCode = json.getString("errCode");
                            retAts.transState = json.getString("errCode");
                            retAts.writeBeforeDetail();
                        } else {
                            retAts.respCode = "0";
                            retAts.respInfo = json.getString("errMsg");
                            retAts.reqSeqID = p_req1998.reqBatchNO;
                            retAts.payInfoCode = json.getString("errCode");
                            retAts.transState = json.getString("errCode");

                            String retFileContent = StrZipUtil.unzip(json.getString("resultFileContent"));
                            //String[] results = retFileContent.split(lineUnionChar);
                            String[] results = retFileContent.split("\n");
                            for (int i = 1; i < results.length; i++) {
                                RetAtsBatPayRecDetail tmpRetDetail = new RetAtsBatPayRecDetail();
                                String[] resultInfo = results[i].split("\\|");
                                tmpRetDetail.result = json.getString("errCode") + "+" + resultInfo[17];
                                tmpRetDetail.memo = resultInfo[18];
                                tmpRetDetail.payInfoCode = json.getString("errCode") + "+" + resultInfo[17];
                                tmpRetDetail.postScript = resultInfo[1];
                                tmpRetDetail.recAct = resultInfo[4];
                                tmpRetDetail.payAmount = StringHelper.amountDivide100(resultInfo[2]);
                                tmpRetDetail.recName = resultInfo[5];
                                retAts.writeRetDetail(tmpRetDetail);
                            }
                        }
                    } else {
                        if (!json.containsKey("batchNo")) {
                            //银行如果没有处理完交易，返回少字段，没有batchNo和fileName，这时候我们校验签名就不通过
                            //这种情况不处理，直接给ATS返回银行处理中，稍后查询
                            retAts.respCode = "0";
                            retAts.respInfo = json.getString("errMsg");
                            retAts.reqSeqID = p_req1998.reqBatchNO;
                            retAts.payInfoCode = json.getString("errCode");
                            retAts.transState = json.getString("errCode");
                        } else {
                            retAts.respCode = "-1";
                            retAts.respInfo = "验签失败";
                        }
                    }
                } else {
                    retAts.respCode = "-1";
                    retAts.respInfo = tmpStrRet[1];
                }
            } else {
                retAts.respCode = "-1";
                retAts.respInfo = "根据当前批次号未能获取到提交银行的批次号，请核查！";
            }
        } catch (Exception e) {
            retAts.respCode = "-1";
            retAts.respInfo = e.getMessage();
            e.printStackTrace();
        }
        if (retAts.respCode.equals("-1") && StringHelper.isNullOrEmpty(retAts.reqSeqID)) {
            retAts.reqSeqID = p_req1998.reqBatchNO;
        }
        if (retAts.respCode.equals("-1")) {
            retAts.writeBeforeDetail();
        }
        retAts.writeAfterDetail();
        return retAts;
    }

    @Override
    public RetAtsQryBatPayRec d_1998_QryBatPay(ReqQryBatPayRec p_req1998) throws Exception {
        RetAtsQryBatPayRec retAts = null;
        if (p_req1998.reqHeader.commandCode.equals("1988F001")) {
            retAts = twoGen_d_1998_QryBatPay(p_req1998);
        } else {
            retAts = oneGen_d_1998_QryBatPay(p_req1998);
        }
        return retAts;
    }


    @Override
    public RetAtsBatPayRec d_9188_BatPay(ReqBatPayRec p_req9188) throws Exception {
        return null;
    }

    @Override
    public RetAtsQryBatPayRec d_9198_QryBatPay(ReqQryBatPayRec p_req9198) throws Exception {
        return null;
    }

    public String write1988FileContent(ReqBatPayRec p_req1988, Integer tatalCount) throws Exception {
        StringBuilder content = new StringBuilder();
        String fieldUnionChar = new String(new byte[]{3});
        while (p_req1988.readRecord()) {
            content.append("\"" + ++tatalCount + "\"").append(fieldUnionChar);//记录序号
            //WorkDayFlag工作日标记，用于大小额判断金额0：工作日     1：非工作日
            if(getBankConfig().getValueAsBool("openLargeAmtPay")){
                content.append("\"HVPS\"").append(fieldUnionChar);//系统类型
                content.append("\"A100\"").append(fieldUnionChar);//业务类型
                content.append("\"02102\"").append(fieldUnionChar);//业务种类
            }else{
                content.append("\"BEPS\"").append(fieldUnionChar);//系统类型
                content.append("\"E100\"").append(fieldUnionChar);//业务类型
                content.append("\"09001\"").append(fieldUnionChar);//业务种类
            }
            if ("1".equals(p_req1988.paySpd)) {
                content.append("\"HIGH\"").append(fieldUnionChar);//业务优先级
            } else {
                content.append("\"NORM\"").append(fieldUnionChar);//业务优先级
            }
            content.append("\"" + p_req1988.readedDetail.payAct + "\"").append(fieldUnionChar);//付款人账号
            content.append("\"" + p_req1988.readedDetail.payName + "\"").append(fieldUnionChar);//付款人名称
            content.append("\"" + p_req1988.readedDetail.payAreaName + "\"").append(fieldUnionChar);//付款人地址
            String CNAPSCode = getBankConfig().getMapAdvanceValue("PayBankInfo", "key", "CNAPSCode", p_req1988.readedDetail.payAct);
            String bankName = getBankConfig().getMapAdvanceValue("PayBankInfo", "key", "bankName", p_req1988.readedDetail.payAct);

            content.append("\"" + CNAPSCode + "\"").append(fieldUnionChar);//付款银行行号
            content.append("\"" + CNAPSCode + "\"").append(fieldUnionChar);//付款开户行行号
            content.append("\"" + bankName + "\"").append(fieldUnionChar);//付款开户行行名
            content.append("\"" + p_req1988.readedDetail.recAct + "\"").append(fieldUnionChar);//收款人账号
            content.append("\"" + p_req1988.readedDetail.recName + "\"").append(fieldUnionChar);//收款人名称
            content.append("\"" + p_req1988.readedDetail.recNameAddress + "\"").append(fieldUnionChar);//收款人地址
            content.append("\"" + p_req1988.readedDetail.cnapsCode + "\"").append(fieldUnionChar);//收款行行号
            content.append("\"" + p_req1988.readedDetail.cnapsCode + "\"").append(fieldUnionChar);//收款开户行行号
            content.append("\"" + p_req1988.readedDetail.cnapsName + "\"").append(fieldUnionChar);//收款开户行行名
            content.append("\"001\"").append(fieldUnionChar);//币种
            content.append(p_req1988.readedDetail.payAmount).append(fieldUnionChar);//金额
            content.append("\"\"").append(fieldUnionChar);//凭证种类
            content.append("\"\"").append(fieldUnionChar);//凭证号码
            content.append("\"" + p_req1988.readedDetail.payAct + "\"").append(fieldUnionChar);//实际付款账号
            content.append("\"" + p_req1988.readedDetail.payName + "\"").append(fieldUnionChar);//实际付款户名
            content.append("\"0\"").append(fieldUnionChar);//手续费收费方式
            content.append("\"\"").append(fieldUnionChar);//费率种类
            content.append("\"\"").append(fieldUnionChar);//收费大类1
            content.append("\"\"").append(fieldUnionChar);//收费种类1
            content.append(fieldUnionChar);//收费金额1
            content.append("\"\"").append(fieldUnionChar);//收费大类2
            content.append("\"\"").append(fieldUnionChar);//收费种类2
            content.append(fieldUnionChar);//收费金额2
            content.append("\"\"").append(fieldUnionChar);//受理柜员
            content.append("\"\"").append(fieldUnionChar);//复核柜员
            content.append("\"\"").append(fieldUnionChar);//授权柜员
            content.append("\"\"").append(fieldUnionChar);//受理柜员名
            content.append("\"\"").append(fieldUnionChar);//复核柜员名
            content.append("\"\"").append(fieldUnionChar);//授权柜员名
            content.append("\"" + p_req1988.readedDetail.memo + "\"").append(fieldUnionChar);//备注
            content.append("\"" + p_req1988.readedDetail.askNumber + "\"").append(fieldUnionChar);//附言
            content.append("\"\"").append(fieldUnionChar);//存折摘要码
            content.append("\"\"").append(fieldUnionChar);//付款帐号圈存流水号
            content.append("\"\"").append(fieldUnionChar);//特色业务交易码
            content.append("\"\"").append(fieldUnionChar);//特色业务优先级
            content.append("\"\"").append(fieldUnionChar);//特色接口1
            content.append("\"\"").append(fieldUnionChar);//银承票号
            content.append("\"\"").append(fieldUnionChar);//出票日期
            content.append(fieldUnionChar);//出票金额
            content.append(fieldUnionChar);//实际结算金额
            content.append(fieldUnionChar);//多余金额
            content.append("\"\"").append(fieldUnionChar);//申请人账号
            content.append("\"\"").append(fieldUnionChar);//申请人名称
            content.append("\n");//换行
        }
        return content.toString();
    }

    private String getPayAmount(String payAmount) throws Exception {
        StringBuilder psb = new StringBuilder(payAmount);
        psb.insert(psb.length() - 2, ".");
        payAmount = psb.toString().replaceAll("^(0+)", "");
        if (payAmount.length() <= 3) {
            payAmount = addCharLeft(4, '0', payAmount);
        }
        return payAmount;
    }
}
